import copy
import time
import inspect
from typing import Any, Callable

def test_function(func: Callable[..., Any], input_args, expected_results, times: int = 1):
    """
    测试给定函数的执行情况，支持以单个字典或数组形式传递参数，并进行多次执行以计算总耗时。
    同时忽略多余的函数输入参数（即过滤掉不在被测函数签名中的参数）。

    参数：
        func (callable): 待测试的函数。
        input_args (dict or list of dict): 输入的参数, 单个字典表示一次调用，数组表示多次调用。
        expected_results (any or list): 单个预期结果或多个预期结果列表。
        times (int): 每次函数调用的执行次数，用于测量总耗时。

    输出：
        每次调用结果是否正确；
        输出错误结果；
        打印所有调用的总计执行时间。
    """
    print(f"Function: {func.__name__}")
    # 获取被测试函数的参数签名，后续用于过滤多余参数
    sig = inspect.signature(func)
    valid_params = set(sig.parameters.keys())

    args_copy = copy.deepcopy(input_args)  # 防止在传入参数为原地操作算法时修改原输入参数

    # 处理参数类型：将单个字典转换为列表形式，确保 args_list 和 expected_results 均为列表
    if isinstance(args_copy, dict):
        args_list = [args_copy]
        expected_results = [expected_results]
    else:
        args_list = args_copy

    all_correct = True  # 标记所有调用是否正确
    total_duration = 0  # 累计总耗时

    for i, args_dict in enumerate(args_list):
        # 过滤多余的参数，只保留 valid_params 中的键
        filtered_args = {k: v for k, v in args_dict.items() if k in valid_params}
        # 为计时保存一份拷贝，防止被原地修改影响后续调用
        timing_args_copy = copy.deepcopy(filtered_args)

        start_time = time.time()
        # 先调用一次获取实际结果
        actual = func(**filtered_args)
        # 剩余 times-1 次调用仅用于计时
        for _ in range(times - 1):
            timing_args = copy.deepcopy(timing_args_copy)
            func(**timing_args)
        duration = time.time() - start_time
        total_duration += duration

        # 判断结果是否与预期一致（这里既可以用“==”也可以考虑 is 的情况）
        if actual == expected_results[i] or actual is expected_results[i]:
            print(f"调用 {i + 1}: 结果正确，耗时: {duration:.6f} 秒")
        else:
            all_correct = False
            print(f"调用 {i + 1}: 结果不正确")
            print(f"  实际输出: {actual}")
            print(f"  预期输出: {expected_results[i]}")

    # 最终输出全部调用的正确性和总耗时
    if all_correct:
        print(f"所有结果均正确, 总耗时 {total_duration:.6f} 秒")
    else:
        print("存在错误结果")
